library(devtools) library(flexdashboard) library(lubridate) library(dplyr) library(ggplot2) library(ggstance) library(ggalt) library(viridisLite)

ggplot(data = fatal_police_shootings_data, aes(y = race)) + 
        geom_bar(aes(fill = ..count..)) +
        theme_minimal(base_size = 13) +
        theme(legend.position = "none") +
        scale_x_continuous(expand=c(0,0)) +
        scale_fill_gradient(low = "royalblue3", high = "navyblue") +
        labs(y = NULL, x = "Number of deaths")

stateinfo <- fatal_police_shootings_data %>% group_by(state) %>% dplyr::summarise(n = n()) %>% 
        dplyr::arrange(desc(n)) %>% top_n(15) %>% 
        mutate(state = factor(state, levels = rev(unique(state))))
Selecting by n
ggplot(stateinfo, aes(x = n, y = state)) +
        geom_bar(stat="identity", aes(fill = n)) +
        geom_text(aes(x = 17, y = state, label=as.character(state)), color="white", size=4) +
        labs(y = NULL, x = "Number of deaths") +
        scale_fill_gradient(low = "grey",
  high = "orange",space = "rgb",
  na.value = "grey50", guide = "colourbar") +
        theme_minimal(base_size = 13) +
        theme(axis.text.y=element_blank()) +
        theme(legend.position = "none") +
        scale_x_continuous(expand=c(0,0))
Warning: Non Lab interpolation is deprecated

levels(fatal_police_shootings_data$gender) <- c("Female", "Male")
levels(fatal_police_shootings_data$race) <- c("Unknown", "Asian", "Black", "Hispanic", "Other", "White")
ggplot(data = knownraced, aes(y = race)) + 
        geom_bar(aes(fill = ..count..)) +
    geom_vline(xintercept = 2500, linetype = 2, colour = "grey20") +
  geom_text(x = 2500, y = 4, label = "majority of\nvictims", 
            hjust = 0, size = 11 * 0.8 / .pt, colour = "grey20") +
  scale_x_continuous(expand = expansion(mult = c(0, 0.1))) +
  scale_y_discrete(limits = rev) +
        theme_minimal(base_size = 13) +
        theme(legend.position = "none") +
        scale_x_continuous(expand=c(0,0)) +
        scale_colour_manual(breaks = c("W", "NA", "O", "B", "A", "H","N"),
                      values = c("NavyBlue", "darkred", "grey","brown", "yellow","darkgreen" , "darkred")) +
        labs(y = NULL, x = "Total of Shootings")
Scale for 'x' is already present. Adding another scale for 'x', which will replace the
existing scale.

ggplot(data = fatal_police_shootings_data, aes(x = age)) + 
        geom_density(fill="#69b3a2", color="#e9ecef",adjust=1.5, alpha=0.4) +
        theme_minimal(base_size = 13) +
        theme(legend.position = "none") +
        scale_x_continuous(expand=c(0,0)) +
        scale_fill_gradient(low = "white", high = "navyblue") +
        labs(x = "Age at death", y = "Density")
Warning: Removed 384 rows containing non-finite values
(stat_density).

armedinfo <- fatal_police_shootings_data %>% group_by(armed) %>% dplyr::summarise(n = n()) %>% 
        arrange(desc(n)) %>% top_n(10) %>% 
        mutate(armed = factor(armed, levels = rev(unique(armed))))
Selecting by n
ggplot(data = armedinfo, aes(x = n, y = armed)) + 
        geom_bar(stat="identity", aes(fill = n)) +
        theme_minimal(base_size = 13) +
        theme(legend.position = "none") +
        scale_x_continuous(expand=c(0,0)) +
        scale_fill_gradient(low = "royalblue3", high = "navyblue") +
        labs(y = NULL, x = "Number of deaths")

genderinfo <- fatal_police_shootings_data %>% group_by(gender) %>% dplyr::summarise(n = n()) 

ggplot(data = genderinfo, aes(x = n, y = gender)) + 
        geom_bar(stat="identity", aes(fill = n)) +
        theme_minimal(base_size = 13) +
        theme(legend.position = "none") +
        scale_x_continuous(expand=c(0,0)) +
        scale_fill_gradient(low = "white", high = "darkgreen") +
        labs(y = NULL, x = "Gender")


mybreaks <- c(0.02, 0.04, 0.08, 1, 7)

data <- fatal_police_shootings_data %>% group_by(fatal_police_shootings_data$state) %>% dplyr::summarise(n = n()) %>% 
        dplyr::arrange(desc(n))

fatal_police_shootings_data %>%
  ggplot() +
    geom_polygon(data = fatal_police_shootings_data, aes(x=fatal_police_shootings_data$longitude, y = fatal_police_shootings_data$latitude), fill="grey", alpha=0.3) +
    geom_point(  aes(x=fatal_police_shootings_data$longitude, y=fatal_police_shootings_data$latitude , size = after_stat(n)), shape=20, stroke=FALSE) +
    scale_size_continuous(name="Shootings Total", range=c(1,1100), breaks=mybreaks) +
    scale_alpha_continuous(name="Shootings Total", range=c(0.1, .9), breaks=mybreaks) +
    scale_color_viridis(option="magma", trans="log", breaks=mybreaks, name="Shootings Total" ) +
    theme_void() + ylim(50,59) + coord_map() + 
    guides( colour = guide_legend()) +
    ggtitle("Shootings Distribution accros the US") +
    theme(
      legend.position = c(0.85, 0.8),
      text = element_text(color = "#22211d"),
      plot.background = element_rect(fill = "#f5f5f2", color = NA), 
      panel.background = element_rect(fill = "#f5f5f2", color = NA), 
      legend.background = element_rect(fill = "#f5f5f2", color = NA),
      plot.title = element_text(size= 16, hjust=0.1, color = "#4e4d47", margin = margin(b = -0.1, t = 0.4, l = 2, unit = "cm")),
    )
Error: Aesthetics must be valid computed stats. Problematic aesthetic(s): size = after_stat(n). 
Did you map your stat in the wrong layer?
Run `rlang::last_error()` to see where the error occurred.

ggplot(data = fatal_police_shootings_data, aes(y = manner_of_death)) + 
        geom_bar(aes(fill = ..count..)) +
        theme_minimal(base_size = 13) +
        theme(legend.position = "none") +
        scale_x_continuous(expand=c(0,0)) +
        scale_fill_gradient(low = "grey", high = "darkred") +
        labs(y = NULL, x = "Number of deaths")

us_cont <- fatal_police_shootings_data[fatal_police_shootings_data$state]
Error: Can't subset columns that don't exist.
x Columns `WA`, `OR`, `KS`, `CA`, `CO`, etc. don't exist.
Run `rlang::last_error()` to see where the error occurred.
yearinfo <- fatal_police_shootings_data %>% group_by(year) %>% dplyr::summarise(n = n())

yearinfo %>% 
  ggplot(aes(x = year, y = n)) +
    geom_line( color="#69b3a2") +
    geom_point(shape=21, color="black", fill="#69b3a2", size=6) +theme_minimal(base_size = 13)+
    ggtitle("Rate of shootings remains steady")

fatal_police_shootings_data <- fatal_police_shootings_data %>%
  mutate(year = lubridate::year(date), 
         month = lubridate::month(date), 
         day = lubridate::day(date))
yearly <- fatal_police_shootings_data %>% group_by(year , month) %>% dplyr::summarise(n = n())
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
yearly %>% 
  ggplot(aes(x= month , y = n , group = year , color = year))+
  geom_line(color="#69b3a2", size=1, alpha=0.9)+
  scale_color_viridis(discrete = TRUE)+
  ggtitle("Rate of Shootings remains steady (2015-2021)")+
  theme_minimal()+
  scale_colour_manual(name = "Year", 
                      values = c("green3", "orange", "blue", "red", "grey")+
  ylab("Total Shootings")
Error: Incomplete expression: yearly %>% 
  ggplot(aes(x= month , y = n , group = year , color = year))+
  geom_line(color="#69b3a2", size=1, alpha=0.9)+
  scale_color_viridis(discrete = TRUE)+
  ggtitle("Rate of Shootings remains steady (2015-2021)")+
  theme_minimal()+
  scale_colour_manual(name = "Year", 
                      values = c("green3", "orange", "blue", "red", "grey")+
  ylab("Total Shootings")
geom_point( data=aqi_map, aes(x=long, y=lat,color=mean_pollution,size=mean_pollution))
Error in fortify(data) : object 'aqi_map' not found
fatal_police_shootings_data%>%
  mutate(fatal_police_shootings_data, region = 
           ifelse(state=="CA"|state=="AZ"|state=="NM"|state=="CO"|state=="ID"|state=="OR"|
                    state=="WA"|state=="AK"|state=="HI", "West",
                  ifelse(state=="TX"|state=="OK"|state=="AR"|state=="LA"|state=="MS"|state=="AL"|
                           state=="TN"|state=="FL"|state=="GA"|state=="NC"|state=="SC"|state=="VA"|
                           state=="KY"|state=="MD"|state=="WV"|state=="DC","South",
                         ifelse(state=="KS"|state=="MO"|state=="IL"|state=="IN"|state=="OH"
                                |state=="IA"|state=="NE"|state=="SD"|state=="ND"|state=="MN"|
                                  state=="WI"|state=="MI","Midwest", "Northeast"))))
fatal_police_shootings_data %>%
summary(subset(fatal_police_shootings_data, region == "Midwest"))
       id           name                date            manner_of_death       armed          
 Min.   :   3   Length:7001        Min.   :2015-01-02   Length:7001        Length:7001       
 1st Qu.:1970   Class :character   1st Qu.:2016-10-12   Class :character   Class :character  
 Median :3883   Mode  :character   Median :2018-07-05   Mode  :character   Mode  :character  
 Mean   :3871                      Mean   :2018-07-16                                        
 3rd Qu.:5771                      3rd Qu.:2020-04-25                                        
 Max.   :7645                      Max.   :2021-12-31                                        
                                                                                             
      age           gender              race               city              state          
 Min.   : 6.00   Length:7001        Length:7001        Length:7001        Length:7001       
 1st Qu.:27.00   Class :character   Class :character   Class :character   Class :character  
 Median :35.00   Mode  :character   Mode  :character   Mode  :character   Mode  :character  
 Mean   :37.13                                                                              
 3rd Qu.:45.00                                                                              
 Max.   :92.00                                                                              
 NA's   :364                                                                                
 signs_of_mental_illness threat_level           flee           body_camera    
 Mode :logical           Length:7001        Length:7001        Mode :logical  
 FALSE:5451              Class :character   Class :character   FALSE:6025     
 TRUE :1550              Mode  :character   Mode  :character   TRUE :976      
                                                                              
                                                                              
                                                                              
                                                                              
   longitude          latitude     is_geocoding_exact      year          month       
 Min.   :-160.01   Min.   :19.50   Mode :logical      Min.   :2015   Min.   : 1.000  
 1st Qu.:-112.07   1st Qu.:33.48   FALSE:18           1st Qu.:2016   1st Qu.: 3.000  
 Median : -94.23   Median :36.10   TRUE :6983         Median :2018   Median : 6.000  
 Mean   : -97.11   Mean   :36.66                      Mean   :2018   Mean   : 6.439  
 3rd Qu.: -83.12   3rd Qu.:40.01                      3rd Qu.:2020   3rd Qu.:10.000  
 Max.   : -67.87   Max.   :71.30                      Max.   :2021   Max.   :12.000  
 NA's   :575       NA's   :575                                                       
      day       
 Min.   : 1.00  
 1st Qu.: 8.00  
 Median :16.00  
 Mean   :15.62  
 3rd Qu.:23.00  
 Max.   :31.00  
                
blacks= fatal_police_shootings_data[fatal_police_shootings_data$race=="B",]
Warning message:
In makeContext(x) : reached elapsed time limit
whites= fatal_police_shootings_data[fatal_police_shootings_data$race=="W",]
hisLats= fatal_police_shootings_data[fatal_police_shootings_data$race=="H",]
summary(blacks)
       id           name                date            manner_of_death   
 Min.   :  17   Length:2665        Min.   :2015-01-06   Length:2665       
 1st Qu.:1726   Class :character   1st Qu.:2016-07-11   Class :character  
 Median :3595   Mode  :character   Median :2018-04-05   Mode  :character  
 Mean   :3586                      Mean   :2018-04-12                     
 3rd Qu.:5350                      3rd Qu.:2019-12-19                     
 Max.   :7645                      Max.   :2021-12-30                     
 NA's   :1082                      NA's   :1082                           
    armed                age           gender              race          
 Length:2665        Min.   :13.00   Length:2665        Length:2665       
 Class :character   1st Qu.:24.00   Class :character   Class :character  
 Mode  :character   Median :31.00   Mode  :character   Mode  :character  
                    Mean   :32.73                                        
                    3rd Qu.:39.00                                        
                    Max.   :88.00                                        
                    NA's   :1113                                         
     city              state           signs_of_mental_illness
 Length:2665        Length:2665        Mode :logical          
 Class :character   Class :character   FALSE:1337             
 Mode  :character   Mode  :character   TRUE :246              
                                       NA's :1082             
                                                              
                                                              
                                                              
 threat_level           flee           body_camera       longitude      
 Length:2665        Length:2665        Mode :logical   Min.   :-157.85  
 Class :character   Class :character   FALSE:1278      1st Qu.: -95.49  
 Mode  :character   Mode  :character   TRUE :305       Median : -87.21  
                                       NA's :1082      Mean   : -90.76  
                                                       3rd Qu.: -80.61  
                                                       Max.   : -70.28  
                                                       NA's   :1170     
    latitude     is_geocoding_exact      year          month       
 Min.   :20.89   Mode :logical      Min.   :2015   Min.   : 1.000  
 1st Qu.:32.95   FALSE:2            1st Qu.:2016   1st Qu.: 3.000  
 Median :36.18   TRUE :1581         Median :2018   Median : 6.000  
 Mean   :36.29   NA's :1082         Mean   :2018   Mean   : 6.244  
 3rd Qu.:39.96                      3rd Qu.:2019   3rd Qu.: 9.000  
 Max.   :61.58                      Max.   :2021   Max.   :12.000  
 NA's   :1170                       NA's   :1082   NA's   :1082    
      day       
 Min.   : 1.00  
 1st Qu.: 8.00  
 Median :15.00  
 Mean   :15.51  
 3rd Qu.:23.00  
 Max.   :31.00  
 NA's   :1082   
summary(whites)
       id           name                date            manner_of_death   
 Min.   :   4   Length:4087        Min.   :2015-01-02   Length:4087       
 1st Qu.:1696   Class :character   1st Qu.:2016-07-03   Class :character  
 Median :3438   Mode  :character   Median :2018-02-17   Mode  :character  
 Mean   :3488                      Mean   :2018-03-09                     
 3rd Qu.:5298                      3rd Qu.:2019-11-26                     
 Max.   :7641                      Max.   :2021-12-26                     
 NA's   :1082                      NA's   :1082                           
    armed                age          gender              race          
 Length:4087        Min.   : 6     Length:4087        Length:4087       
 Class :character   1st Qu.:30     Class :character   Class :character  
 Mode  :character   Median :38     Mode  :character   Mode  :character  
                    Mean   :40                                          
                    3rd Qu.:49                                          
                    Max.   :91                                          
                    NA's   :1129                                        
     city              state           signs_of_mental_illness
 Length:4087        Length:4087        Mode :logical          
 Class :character   Class :character   FALSE:2130             
 Mode  :character   Mode  :character   TRUE :875              
                                       NA's :1082             
                                                              
                                                              
                                                              
 threat_level           flee           body_camera       longitude      
 Length:4087        Length:4087        Mode :logical   Min.   :-158.02  
 Class :character   Class :character   FALSE:2682      1st Qu.:-107.59  
 Mode  :character   Mode  :character   TRUE :323       Median : -91.61  
                                       NA's :1082      Mean   : -95.37  
                                                       3rd Qu.: -82.73  
                                                       Max.   : -68.03  
                                                       NA's   :1252     
    latitude     is_geocoding_exact      year          month      
 Min.   :21.28   Mode :logical      Min.   :2015   Min.   : 1.00  
 1st Qu.:33.77   FALSE:4            1st Qu.:2016   1st Qu.: 3.00  
 Median :36.87   TRUE :3001         Median :2018   Median : 6.00  
 Mean   :37.39   NA's :1082         Mean   :2018   Mean   : 6.17  
 3rd Qu.:40.68                      3rd Qu.:2019   3rd Qu.: 9.00  
 Max.   :64.86                      Max.   :2021   Max.   :12.00  
 NA's   :1252                       NA's   :1082   NA's   :1082   
      day       
 Min.   : 1.00  
 1st Qu.: 8.00  
 Median :15.00  
 Mean   :15.44  
 3rd Qu.:23.00  
 Max.   :31.00  
 NA's   :1082   
summary(hisLats)
       id           name                date            manner_of_death   
 Min.   :   5   Length:2169        Min.   :2015-01-03   Length:2169       
 1st Qu.:1782   Class :character   1st Qu.:2016-08-08   Class :character  
 Median :3455   Mode  :character   Median :2018-02-25   Mode  :character  
 Mean   :3481                      Mean   :2018-03-07                     
 3rd Qu.:5094                      3rd Qu.:2019-09-18                     
 Max.   :7600                      Max.   :2021-12-26                     
 NA's   :1082                      NA's   :1082                           
    armed                age           gender              race          
 Length:2169        Min.   :13.00   Length:2169        Length:2169       
 Class :character   1st Qu.:26.00   Class :character   Class :character  
 Mode  :character   Median :33.00   Mode  :character   Mode  :character  
                    Mean   :33.72                                        
                    3rd Qu.:40.00                                        
                    Max.   :80.00                                        
                    NA's   :1111                                         
     city              state           signs_of_mental_illness
 Length:2169        Length:2169        Mode :logical          
 Class :character   Class :character   FALSE:897              
 Mode  :character   Mode  :character   TRUE :190              
                                       NA's :1082             
                                                              
                                                              
                                                              
 threat_level           flee           body_camera       longitude      
 Length:2169        Length:2169        Mode :logical   Min.   :-157.88  
 Class :character   Class :character   FALSE:925       1st Qu.:-118.19  
 Mode  :character   Mode  :character   TRUE :162       Median :-111.00  
                                       NA's :1082      Mean   :-106.26  
                                                       3rd Qu.: -97.51  
                                                       Max.   : -70.79  
                                                       NA's   :1123     
    latitude     is_geocoding_exact      year          month       
 Min.   :21.32   Mode :logical      Min.   :2015   Min.   : 1.000  
 1st Qu.:32.82   FALSE:2            1st Qu.:2016   1st Qu.: 3.000  
 Median :34.09   TRUE :1085         Median :2018   Median : 6.000  
 Mean   :34.96   NA's :1082         Mean   :2018   Mean   : 6.159  
 3rd Qu.:37.61                      3rd Qu.:2019   3rd Qu.: 9.000  
 Max.   :48.75                      Max.   :2021   Max.   :12.000  
 NA's   :1123                       NA's   :1082   NA's   :1082    
      day       
 Min.   : 1.00  
 1st Qu.: 8.00  
 Median :16.00  
 Mean   :15.74  
 3rd Qu.:23.00  
 Max.   :31.00  
 NA's   :1082   
ggplot(fatal_police_shootings_data,aes(x=age)) + 
  geom_histogram(data=subset(fatal_police_shootings_data,race == 'B'),fill = "red", alpha = 0.2,binwidth = 1) +
  geom_histogram(data=subset(fatal_police_shootings_data,race == 'W'),fill = "blue", alpha = 0.2,binwidth = 1) +
  geom_histogram(data=subset(fatal_police_shootings_data,race == 'H'),fill = "yellow", alpha = 0.3,binwidth = 1)
Warning: Removed 31 rows containing non-finite values (stat_bin).
Warning: Removed 47 rows containing non-finite values (stat_bin).
Warning: Removed 29 rows containing non-finite values (stat_bin).

p1=ggplot(hisLats, aes(age))+ 
  geom_histogram(color="black",fill="pink",binwidth=1, alpha=0.8)+
  ggtitle("Individuals killed by age- Race/ethnicity: Hispanic/latino") + xlim(6, 87)
p2=ggplot(blacks, aes(age))+ 
  geom_histogram(color="black",fill="green",binwidth=1, alpha=0.3)+
  ggtitle("Individuals killed by age- Race/ethnicity: Black") + xlim(6, 87)
p3=ggplot(whites, aes(age))+ 
  geom_histogram(color="black",fill="pink",binwidth=1, alpha=0.3)+
  ggtitle("Individuals killed by age- Race/ethnicity: White") + xlim(6, 87)
g1 <- ggplotGrob(p1)
Warning: Removed 1111 rows containing non-finite values (stat_bin).
Warning: Removed 2 rows containing missing values (geom_bar).
g2 <- ggplotGrob(p2)
Warning: Removed 1114 rows containing non-finite values (stat_bin).
Warning: Removed 2 rows containing missing values (geom_bar).
g3 <- ggplotGrob(p3)
Warning: Removed 1131 rows containing non-finite values (stat_bin).
Warning: Removed 2 rows containing missing values (geom_bar).
g <- rbind(g1,g2, g3, size = "first")
g$widths <- unit.pmax(g1$widths,g2$widths, g3$widths)
grid.newpage()

grid.draw(g)

# Age break down with armed by region
ggplot(data=fatal_police_shootings_data,aes(x=fatal_police_shootings_data$region,y=age,  fill=armed ))+
  geom_boxplot(outlier.colour="Black",  outlier.size=1, notch=FALSE)+
  labs(x='Race/Ethnicity', y= 'Age')+
  ggtitle("Age and 'armed' status of deceased by region")
Warning: Unknown or uninitialised column: `region`.
Warning: Unknown or uninitialised column: `region`.
Warning: Removed 364 rows containing non-finite values (stat_boxplot).

# Age break down with classification/cause of death by region
ggplot(data=fatal_police_shootings_data,aes(x=fatal_police_shootings_data$region,y=age,  fill=manner_of_death ))+
  geom_boxplot(outlier.colour="Black",  outlier.size=1, notch=FALSE)+
  labs(x='Race/Ethnicity', y= 'Age')+
  ggtitle("Age and cause of death")
Warning: Unknown or uninitialised column: `region`.
Warning: Unknown or uninitialised column: `region`.
Warning: Removed 364 rows containing non-finite values (stat_boxplot).

# Age breakdown with race by region
ggplot(data=fatal_police_shootings_data,aes(x=fatal_police_shootings_data$region,y=age,  fill=race))+
  geom_boxplot(outlier.colour="Black",  outlier.size=1, notch=FALSE)+
  labs(x='Region', y= 'Age')
Warning: Unknown or uninitialised column: `region`.
Warning: Unknown or uninitialised column: `region`.
Warning: Removed 364 rows containing non-finite values (stat_boxplot).

knownraced %>% group_by(race) %>% dplyr::summarise(n = n())
ggplot(knownraced,aes(race)) + 
  geom_bar(fill="royalblue") +
  ggtitle("Killings vs race/ethnicity of deceased")

library(tmap)
Warning: package ‘tmap’ was built under R version 4.1.2
library(tmaptools)
Warning: package ‘tmaptools’ was built under R version 4.1.2
shape <- read_sf("~/Assignment 1/USA_States_Generalized.shp")
{map_US + map_AL+ map_HI +  tm_shape(shootings_sf)+tm_dots(size= 0.1, col="race", title= "Race", id="name", popup.vars = c("Age:" = "age", "Gender:" = "gender","Date Killed:"="date", "Armed:"="armed","Fleeing:"="flee", "Signs of Mental Health Issues:" = "signs_of_mental_illness","Manner of Death: " = "manner_of_death","State:" = "state"))+
      tm_layout(title= "Map of Deadly Force US Police Shootings Jan 2015- December 2021",title.position = c('right', 'top'))+tmap_mode("view")}
tmap mode set to interactive viewing
legend.postion is used for plot mode. Use view.legend.position in tm_view to set the legend position in view mode.

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KbGlicmFyeShkZXZ0b29scykNCmxpYnJhcnkoZmxleGRhc2hib2FyZCkNCmxpYnJhcnkobHVicmlkYXRlKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZ2dzdGFuY2UpDQpsaWJyYXJ5KGdnYWx0KQ0KbGlicmFyeSh2aXJpZGlzTGl0ZSkNCg0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IGZhdGFsX3BvbGljZV9zaG9vdGluZ3NfZGF0YSwgYWVzKHkgPSByYWNlKSkgKyANCiAgICAgICAgZ2VvbV9iYXIoYWVzKGZpbGwgPSAuLmNvdW50Li4pKSArDQogICAgICAgIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTMpICsNCiAgICAgICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogICAgICAgIHNjYWxlX3hfY29udGludW91cyhleHBhbmQ9YygwLDApKSArDQogICAgICAgIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gInJveWFsYmx1ZTMiLCBoaWdoID0gIm5hdnlibHVlIikgKw0KICAgICAgICBsYWJzKHkgPSBOVUxMLCB4ID0gIk51bWJlciBvZiBkZWF0aHMiKQ0KYGBgDQoNCg0KDQpgYGB7cn0NCnN0YXRlaW5mbyA8LSBmYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGEgJT4lIGdyb3VwX2J5KHN0YXRlKSAlPiUgZHBseXI6OnN1bW1hcmlzZShuID0gbigpKSAlPiUgDQogICAgICAgIGRwbHlyOjphcnJhbmdlKGRlc2MobikpICU+JSB0b3BfbigxNSkgJT4lIA0KICAgICAgICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IHJldih1bmlxdWUoc3RhdGUpKSkpDQpnZ3Bsb3Qoc3RhdGVpbmZvLCBhZXMoeCA9IG4sIHkgPSBzdGF0ZSkpICsNCiAgICAgICAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBhZXMoZmlsbCA9IG4pKSArDQogICAgICAgIGdlb21fdGV4dChhZXMoeCA9IDE3LCB5ID0gc3RhdGUsIGxhYmVsPWFzLmNoYXJhY3RlcihzdGF0ZSkpLCBjb2xvcj0id2hpdGUiLCBzaXplPTQpICsNCiAgICAgICAgbGFicyh5ID0gTlVMTCwgeCA9ICJOdW1iZXIgb2YgZGVhdGhzIikgKw0KICAgICAgICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJncmV5IiwNCiAgaGlnaCA9ICJvcmFuZ2UiLHNwYWNlID0gInJnYiIsDQogIG5hLnZhbHVlID0gImdyZXk1MCIsIGd1aWRlID0gImNvbG91cmJhciIpICsNCiAgICAgICAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAxMykgKw0KICAgICAgICB0aGVtZShheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCkpICsNCiAgICAgICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogICAgICAgIHNjYWxlX3hfY29udGludW91cyhleHBhbmQ9YygwLDApKQ0KYGBgDQoNCmBgYHtyfQ0KbGV2ZWxzKGZhdGFsX3BvbGljZV9zaG9vdGluZ3NfZGF0YSRnZW5kZXIpIDwtIGMoIkZlbWFsZSIsICJNYWxlIikNCmxldmVscyhmYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGEkcmFjZSkgPC0gYygiVW5rbm93biIsICJBc2lhbiIsICJCbGFjayIsICJIaXNwYW5pYyIsICJPdGhlciIsICJXaGl0ZSIpDQpgYGANCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBrbm93bnJhY2VkLCBhZXMoeSA9IHJhY2UpKSArIA0KICAgICAgICBnZW9tX2JhcihhZXMoZmlsbCA9IC4uY291bnQuLikpICsNCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAyNTAwLCBsaW5ldHlwZSA9IDIsIGNvbG91ciA9ICJncmV5MjAiKSArDQogIGdlb21fdGV4dCh4ID0gMjUwMCwgeSA9IDQsIGxhYmVsID0gIm1ham9yaXR5IG9mXG52aWN0aW1zIiwgDQogICAgICAgICAgICBoanVzdCA9IDAsIHNpemUgPSAxMSAqIDAuOCAvIC5wdCwgY29sb3VyID0gImdyZXkyMCIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGV4cGFuZCA9IGV4cGFuc2lvbihtdWx0ID0gYygwLCAwLjEpKSkgKw0KICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cyA9IHJldikgKw0KICAgICAgICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDEzKSArDQogICAgICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICAgICAgICBzY2FsZV94X2NvbnRpbnVvdXMoZXhwYW5kPWMoMCwwKSkgKw0KICAgICAgICBzY2FsZV9jb2xvdXJfbWFudWFsKGJyZWFrcyA9IGMoIlciLCAiTkEiLCAiTyIsICJCIiwgIkEiLCAiSCIsIk4iKSwNCiAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBjKCJOYXZ5Qmx1ZSIsICJkYXJrcmVkIiwgImdyZXkiLCJicm93biIsICJ5ZWxsb3ciLCJkYXJrZ3JlZW4iICwgImRhcmtyZWQiKSkgKw0KICAgICAgICBsYWJzKHkgPSBOVUxMLCB4ID0gIlRvdGFsIG9mIFNob290aW5ncyIpDQpgYGANCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBmYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGEsIGFlcyh4ID0gYWdlKSkgKyANCiAgICAgICAgZ2VvbV9kZW5zaXR5KGZpbGw9IiM2OWIzYTIiLCBjb2xvcj0iI2U5ZWNlZiIsYWRqdXN0PTEuNSwgYWxwaGE9MC40KSArDQogICAgICAgIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTMpICsNCiAgICAgICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogICAgICAgIHNjYWxlX3hfY29udGludW91cyhleHBhbmQ9YygwLDApKSArDQogICAgICAgIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gIndoaXRlIiwgaGlnaCA9ICJuYXZ5Ymx1ZSIpICsNCiAgICAgICAgbGFicyh4ID0gIkFnZSBhdCBkZWF0aCIsIHkgPSAiRGVuc2l0eSIpDQpgYGANCg0KYGBge3J9DQphcm1lZGluZm8gPC0gZmF0YWxfcG9saWNlX3Nob290aW5nc19kYXRhICU+JSBncm91cF9ieShhcm1lZCkgJT4lIGRwbHlyOjpzdW1tYXJpc2UobiA9IG4oKSkgJT4lIA0KICAgICAgICBhcnJhbmdlKGRlc2MobikpICU+JSB0b3BfbigxMCkgJT4lIA0KICAgICAgICBtdXRhdGUoYXJtZWQgPSBmYWN0b3IoYXJtZWQsIGxldmVscyA9IHJldih1bmlxdWUoYXJtZWQpKSkpDQoNCmdncGxvdChkYXRhID0gYXJtZWRpbmZvLCBhZXMoeCA9IG4sIHkgPSBhcm1lZCkpICsgDQogICAgICAgIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IiwgYWVzKGZpbGwgPSBuKSkgKw0KICAgICAgICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDEzKSArDQogICAgICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICAgICAgICBzY2FsZV94X2NvbnRpbnVvdXMoZXhwYW5kPWMoMCwwKSkgKw0KICAgICAgICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJyb3lhbGJsdWUzIiwgaGlnaCA9ICJuYXZ5Ymx1ZSIpICsNCiAgICAgICAgbGFicyh5ID0gTlVMTCwgeCA9ICJOdW1iZXIgb2YgZGVhdGhzIikNCmBgYA0KYGBge3J9DQpnZW5kZXJpbmZvIDwtIGZhdGFsX3BvbGljZV9zaG9vdGluZ3NfZGF0YSAlPiUgZ3JvdXBfYnkoZ2VuZGVyKSAlPiUgZHBseXI6OnN1bW1hcmlzZShuID0gbigpKSANCg0KZ2dwbG90KGRhdGEgPSBnZW5kZXJpbmZvLCBhZXMoeCA9IG4sIHkgPSBnZW5kZXIpKSArIA0KICAgICAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIGFlcyhmaWxsID0gbikpICsNCiAgICAgICAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAxMykgKw0KICAgICAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsNCiAgICAgICAgc2NhbGVfeF9jb250aW51b3VzKGV4cGFuZD1jKDAsMCkpICsNCiAgICAgICAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAid2hpdGUiLCBoaWdoID0gImRhcmtncmVlbiIpICsNCiAgICAgICAgbGFicyh5ID0gTlVMTCwgeCA9ICJHZW5kZXIiKQ0KYGBgDQoNCmBgYHtyfQ0KDQpteWJyZWFrcyA8LSBjKDAuMDIsIDAuMDQsIDAuMDgsIDEsIDcpDQoNCmRhdGEgPC0gZmF0YWxfcG9saWNlX3Nob290aW5nc19kYXRhICU+JSBncm91cF9ieShmYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGEkc3RhdGUpICU+JSBkcGx5cjo6c3VtbWFyaXNlKG4gPSBuKCkpICU+JSANCiAgICAgICAgZHBseXI6OmFycmFuZ2UoZGVzYyhuKSkNCg0KZmF0YWxfcG9saWNlX3Nob290aW5nc19kYXRhICU+JQ0KICBnZ3Bsb3QoKSArDQogICAgZ2VvbV9wb2x5Z29uKGRhdGEgPSBmYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGEsIGFlcyh4PWZhdGFsX3BvbGljZV9zaG9vdGluZ3NfZGF0YSRsb25naXR1ZGUsIHkgPSBmYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGEkbGF0aXR1ZGUpLCBmaWxsPSJncmV5IiwgYWxwaGE9MC4zKSArDQogICAgZ2VvbV9wb2ludCggIGFlcyh4PWZhdGFsX3BvbGljZV9zaG9vdGluZ3NfZGF0YSRsb25naXR1ZGUsIHk9ZmF0YWxfcG9saWNlX3Nob290aW5nc19kYXRhJGxhdGl0dWRlICwgc2l6ZSA9IGFmdGVyX3N0YXQobikpLCBzaGFwZT0yMCwgc3Ryb2tlPUZBTFNFKSArDQogICAgc2NhbGVfc2l6ZV9jb250aW51b3VzKG5hbWU9IlNob290aW5ncyBUb3RhbCIsIHJhbmdlPWMoMSwxMTAwKSwgYnJlYWtzPW15YnJlYWtzKSArDQogICAgc2NhbGVfYWxwaGFfY29udGludW91cyhuYW1lPSJTaG9vdGluZ3MgVG90YWwiLCByYW5nZT1jKDAuMSwgLjkpLCBicmVha3M9bXlicmVha3MpICsNCiAgICBzY2FsZV9jb2xvcl92aXJpZGlzKG9wdGlvbj0ibWFnbWEiLCB0cmFucz0ibG9nIiwgYnJlYWtzPW15YnJlYWtzLCBuYW1lPSJTaG9vdGluZ3MgVG90YWwiICkgKw0KICAgIHRoZW1lX3ZvaWQoKSArIHlsaW0oNTAsNTkpICsgY29vcmRfbWFwKCkgKyANCiAgICBndWlkZXMoIGNvbG91ciA9IGd1aWRlX2xlZ2VuZCgpKSArDQogICAgZ2d0aXRsZSgiU2hvb3RpbmdzIERpc3RyaWJ1dGlvbiBhY2Nyb3NzIHRoZSBVUyIpICsNCiAgICB0aGVtZSgNCiAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC44NSwgMC44KSwNCiAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiIzIyMjExZCIpLA0KICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI2Y1ZjVmMiIsIGNvbG9yID0gTkEpLCANCiAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjZjVmNWYyIiwgY29sb3IgPSBOQSksIA0KICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjZjVmNWYyIiwgY29sb3IgPSBOQSksDQogICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9IDE2LCBoanVzdD0wLjEsIGNvbG9yID0gIiM0ZTRkNDciLCBtYXJnaW4gPSBtYXJnaW4oYiA9IC0wLjEsIHQgPSAwLjQsIGwgPSAyLCB1bml0ID0gImNtIikpLA0KICAgICkNCmBgYA0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IGZhdGFsX3BvbGljZV9zaG9vdGluZ3NfZGF0YSwgYWVzKHkgPSBtYW5uZXJfb2ZfZGVhdGgpKSArIA0KICAgICAgICBnZW9tX2JhcihhZXMoZmlsbCA9IC4uY291bnQuLikpICsNCiAgICAgICAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAxMykgKw0KICAgICAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsNCiAgICAgICAgc2NhbGVfeF9jb250aW51b3VzKGV4cGFuZD1jKDAsMCkpICsNCiAgICAgICAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiZ3JleSIsIGhpZ2ggPSAiZGFya3JlZCIpICsNCiAgICAgICAgbGFicyh5ID0gTlVMTCwgeCA9ICJOdW1iZXIgb2YgZGVhdGhzIikNCmBgYA0KDQpgYGB7cn0NCnVzX2NvbnQgPC0gZmF0YWxfcG9saWNlX3Nob290aW5nc19kYXRhW2ZhdGFsX3BvbGljZV9zaG9vdGluZ3NfZGF0YSRzdGF0ZV0NCg0KVVNfYm91bmQgPC0gdG1fc2hhcGUodXNfY29udCwgcHJvamVjdGlvbj0yMTYzKQ0KDQptYXBfVVMgPC0gVVNfYm91bmQgKw0KICB0bV9wb2x5Z29ucyhjb2w9IndoaXRlIikgKyB0bV90ZXh0KCJTVEFURV9OQU1FIikrDQogIHRtX2xheW91dChmcmFtZT1GQUxTRSwNCiAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoInJpZ2h0IiwgImJvdHRvbSIpLCBiZy5jb2xvcj0ibGlnaHRibHVlIiwNCiAgICAgICAgICAgIGlubmVyLm1hcmdpbnMgPSBjKC4yNSwuMDIsLjAyLC4wMikpDQpgYGANCmBgYHtyfQ0KeWVhcmluZm8gPC0gZmF0YWxfcG9saWNlX3Nob290aW5nc19kYXRhICU+JSBncm91cF9ieSh5ZWFyKSAlPiUgZHBseXI6OnN1bW1hcmlzZShuID0gbigpKQ0KDQp5ZWFyaW5mbyAlPiUgDQogIGdncGxvdChhZXMoeCA9IHllYXIsIHkgPSBuKSkgKw0KICAgIGdlb21fbGluZSggY29sb3I9IiM2OWIzYTIiKSArDQogICAgZ2VvbV9wb2ludChzaGFwZT0yMSwgY29sb3I9ImJsYWNrIiwgZmlsbD0iIzY5YjNhMiIsIHNpemU9NikgK3RoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTMpKw0KICAgIGdndGl0bGUoIlJhdGUgb2Ygc2hvb3RpbmdzIHJlbWFpbnMgc3RlYWR5IikNCmBgYA0KYGBge3J9DQpmYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGEgPC0gZmF0YWxfcG9saWNlX3Nob290aW5nc19kYXRhICU+JQ0KICBtdXRhdGUoeWVhciA9IGx1YnJpZGF0ZTo6eWVhcihkYXRlKSwgDQogICAgICAgICBtb250aCA9IGx1YnJpZGF0ZTo6bW9udGgoZGF0ZSksIA0KICAgICAgICAgZGF5ID0gbHVicmlkYXRlOjpkYXkoZGF0ZSkpDQpgYGANCmBgYHtyfQ0KeWVhcmx5IDwtIGZhdGFsX3BvbGljZV9zaG9vdGluZ3NfZGF0YSAlPiUgZ3JvdXBfYnkoeWVhciAsIG1vbnRoKSAlPiUgZHBseXI6OnN1bW1hcmlzZShuID0gbigpKQ0KDQoNCnllYXJseSAlPiUgDQogIGdncGxvdChhZXMoeD0gbW9udGggLCB5ID0gbiAsIGdyb3VwID0geWVhciAsIGNvbG9yID0geWVhcikpKw0KICBnZW9tX2xpbmUoY29sb3I9IiM2OWIzYTIiLCBzaXplPTEsIGFscGhhPTAuOSkrDQogIHNjYWxlX2NvbG9yX3ZpcmlkaXMoZGlzY3JldGUgPSBUUlVFKSsNCiAgZ2d0aXRsZSgiUmF0ZSBvZiBTaG9vdGluZ3MgcmVtYWlucyBzdGVhZHkgKDIwMTUtMjAyMSkiKSsNCiAgdGhlbWVfbWluaW1hbCgpKw0KICBzY2FsZV9jb2xvdXJfbWFudWFsKG5hbWUgPSAiWWVhciIsIA0KICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGMoImdyZWVuMyIsICJvcmFuZ2UiLCAiYmx1ZSIsICJyZWQiLCAiZ3JleSIpKw0KICB5bGFiKCJUb3RhbCBTaG9vdGluZ3MiKQ0KYGBgDQpgYGB7cn0NCmZpZygxMiw4KQ0KDQpgYGANCmBgYHtyfQ0KZGYgPC0gZmF0YWxfcG9saWNlX3Nob290aW5nc19kYXRhICU+JQ0KY291bnQoc3RhdGUpDQoNCmZhdGFsX3BvbGljZV9zaG9vdGluZ3NfZGF0YSAlPiUNCmxlZnRfam9pbigNCmRmLA0KYnkgPSAic3RhdGUiKQ0KDQojIENyZWF0ZSB0aGUgbWFwDQoNCmZhdGFsX3BvbGljZV9zaG9vdGluZ3NfZGF0YSAlPiUNCmdncGxvdCgpICsNCiAgZ2VvbV9wb2x5Z29uKGFlcyhmYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGEkbG9uZ2l0dWRlLCBmYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGEkbGF0aXR1ZGUsZ3JvdXAgPSBmYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGEkc3RhdGUsIGZpbGwgPSBmYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGEkbiksIGNvbG9yID0gIndoaXRlIiwgZmlsbD0iZ3JleSIsIGFscGhhPTAuMykgKw0KIGNvb3JkX21hcCgiYm9ubmUiLCBwYXJhbWV0ZXJzID0gNDUpICsNCnNjYWxlX2NvbG9yX2dyYWRpZW50KGxvdyA9ICJncmVlbiIsIGhpZ2ggPSAicmVkIikrDQogIGxhYnMoY29sb3I9Ik51bWJlciBvZiBTaG9vdGluZ3MiLA0KICAgICAgIHRpdGxlID0gIkZhdGFsIFBvbGljZSBTaG9vdGluZ3MgaW4gVW5pdGVzIFN0YXRlcyIsIA0KICAgICAgIHNpemU9Ik51bWJlciBvZiBTaG9vdGluZ3MiKSsNCnRoZW1lX2J3KCkrDQp0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MjIpDQogICAgICAsYXhpcy50ZXh0Lng9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwNCiAgICAgICBheGlzLnRleHQueT0gZWxlbWVudF90ZXh0KHNpemU9MTUpLA0KICAgICAgICBheGlzLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTE4KSkNCmBgYA0KYGBge3J9DQpmYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGElPiUNCiAgbXV0YXRlKGZhdGFsX3BvbGljZV9zaG9vdGluZ3NfZGF0YSwgcmVnaW9uID0gDQogICAgICAgICAgIGlmZWxzZShzdGF0ZT09IkNBInxzdGF0ZT09IkFaInxzdGF0ZT09Ik5NInxzdGF0ZT09IkNPInxzdGF0ZT09IklEInxzdGF0ZT09Ik9SInwNCiAgICAgICAgICAgICAgICAgICAgc3RhdGU9PSJXQSJ8c3RhdGU9PSJBSyJ8c3RhdGU9PSJISSIsICJXZXN0IiwNCiAgICAgICAgICAgICAgICAgIGlmZWxzZShzdGF0ZT09IlRYInxzdGF0ZT09Ik9LInxzdGF0ZT09IkFSInxzdGF0ZT09IkxBInxzdGF0ZT09Ik1TInxzdGF0ZT09IkFMInwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlPT0iVE4ifHN0YXRlPT0iRkwifHN0YXRlPT0iR0EifHN0YXRlPT0iTkMifHN0YXRlPT0iU0MifHN0YXRlPT0iVkEifA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGU9PSJLWSJ8c3RhdGU9PSJNRCJ8c3RhdGU9PSJXViJ8c3RhdGU9PSJEQyIsIlNvdXRoIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uoc3RhdGU9PSJLUyJ8c3RhdGU9PSJNTyJ8c3RhdGU9PSJJTCJ8c3RhdGU9PSJJTiJ8c3RhdGU9PSJPSCINCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHN0YXRlPT0iSUEifHN0YXRlPT0iTkUifHN0YXRlPT0iU0QifHN0YXRlPT0iTkQifHN0YXRlPT0iTU4ifA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlPT0iV0kifHN0YXRlPT0iTUkiLCJNaWR3ZXN0IiwgIk5vcnRoZWFzdCIpKSkpDQpgYGANCmBgYHtyfQ0KZmF0YWxfcG9saWNlX3Nob290aW5nc19kYXRhICU+JQ0Kc3VtbWFyeShzdWJzZXQoZmF0YWxfcG9saWNlX3Nob290aW5nc19kYXRhLCByZWdpb24gPT0gIk1pZHdlc3QiKSkNCmBgYA0KDQpgYGB7cn0NCmJsYWNrcz0gZmF0YWxfcG9saWNlX3Nob290aW5nc19kYXRhW2ZhdGFsX3BvbGljZV9zaG9vdGluZ3NfZGF0YSRyYWNlPT0iQiIsXQ0Kd2hpdGVzPSBmYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGFbZmF0YWxfcG9saWNlX3Nob290aW5nc19kYXRhJHJhY2U9PSJXIixdDQpoaXNMYXRzPSBmYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGFbZmF0YWxfcG9saWNlX3Nob290aW5nc19kYXRhJHJhY2U9PSJIIixdDQpzdW1tYXJ5KGJsYWNrcykNCnN1bW1hcnkod2hpdGVzKQ0Kc3VtbWFyeShoaXNMYXRzKQ0KYGBgDQpgYGB7cn0NCmZhdGFsX3BvbGljZV9zaG9vdGluZ3NfZGF0YSU+JSBtdXRhdGUoZmF0YWxfcG9saWNlX3Nob290aW5nc19kYXRhLCBhZ2Vncm91cCA9IA0KICAgICAgICAgICBpZmVsc2UoYWdlPDE4LCAidW5kZXItMTgiLA0KICAgICAgICAgICAgICAgICAgaWZlbHNlKGFnZT4xNyAmIGFnZTwzNiwiMTgtMzUiLCJvdmVyIDM1IikpKQ0KDQpmYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGElPiUNCmdncGxvdChmYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGEsYWVzKHg9YWdlKSkgKyANCiAgZ2VvbV9oaXN0b2dyYW0oZGF0YT1zdWJzZXQoZmF0YWxfcG9saWNlX3Nob290aW5nc19kYXRhLHJhY2UgPT0gJ0InKSxmaWxsID0gInJlZCIsIGFscGhhID0gMC4yLGJpbndpZHRoID0gMSkgKw0KICBnZW9tX2hpc3RvZ3JhbShkYXRhPXN1YnNldChmYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGEscmFjZSA9PSAnVycpLGZpbGwgPSAiYmx1ZSIsIGFscGhhID0gMC4yLGJpbndpZHRoID0gMSkgKw0KICBnZW9tX2hpc3RvZ3JhbShkYXRhPXN1YnNldChmYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGEscmFjZSA9PSAnSCcpLGZpbGwgPSAieWVsbG93IiwgYWxwaGEgPSAwLjMsYmlud2lkdGggPSAxKQ0KYGBgDQpgYGB7cn0NCnAxPWdncGxvdChoaXNMYXRzLCBhZXMoYWdlKSkrIA0KICBnZW9tX2hpc3RvZ3JhbShjb2xvcj0iYmxhY2siLGZpbGw9InBpbmsiLGJpbndpZHRoPTEsIGFscGhhPTAuOCkrDQogIGdndGl0bGUoIkluZGl2aWR1YWxzIGtpbGxlZCBieSBhZ2UtIFJhY2UvZXRobmljaXR5OiBIaXNwYW5pYy9sYXRpbm8iKSArIHhsaW0oNiwgODcpDQpwMj1nZ3Bsb3QoYmxhY2tzLCBhZXMoYWdlKSkrIA0KICBnZW9tX2hpc3RvZ3JhbShjb2xvcj0iYmxhY2siLGZpbGw9ImdyZWVuIixiaW53aWR0aD0xLCBhbHBoYT0wLjMpKw0KICBnZ3RpdGxlKCJJbmRpdmlkdWFscyBraWxsZWQgYnkgYWdlLSBSYWNlL2V0aG5pY2l0eTogQmxhY2siKSArIHhsaW0oNiwgODcpDQpwMz1nZ3Bsb3Qod2hpdGVzLCBhZXMoYWdlKSkrIA0KICBnZW9tX2hpc3RvZ3JhbShjb2xvcj0iYmxhY2siLGZpbGw9InBpbmsiLGJpbndpZHRoPTEsIGFscGhhPTAuMykrDQogIGdndGl0bGUoIkluZGl2aWR1YWxzIGtpbGxlZCBieSBhZ2UtIFJhY2UvZXRobmljaXR5OiBXaGl0ZSIpICsgeGxpbSg2LCA4NykNCmcxIDwtIGdncGxvdEdyb2IocDEpDQpnMiA8LSBnZ3Bsb3RHcm9iKHAyKQ0KZzMgPC0gZ2dwbG90R3JvYihwMykNCmcgPC0gcmJpbmQoZzEsZzIsIGczLCBzaXplID0gImZpcnN0IikNCmckd2lkdGhzIDwtIHVuaXQucG1heChnMSR3aWR0aHMsZzIkd2lkdGhzLCBnMyR3aWR0aHMpDQpncmlkLm5ld3BhZ2UoKQ0KZ3JpZC5kcmF3KGcpDQpgYGANCmBgYHtyfQ0KIyBBZ2UgYnJlYWsgZG93biB3aXRoIGFybWVkIGJ5IHJlZ2lvbg0KZ2dwbG90KGRhdGE9ZmF0YWxfcG9saWNlX3Nob290aW5nc19kYXRhLGFlcyh4PWZhdGFsX3BvbGljZV9zaG9vdGluZ3NfZGF0YSRyZWdpb24seT1hZ2UsICBmaWxsPWFybWVkICkpKw0KICBnZW9tX2JveHBsb3Qob3V0bGllci5jb2xvdXI9IkJsYWNrIiwgIG91dGxpZXIuc2l6ZT0xLCBub3RjaD1GQUxTRSkrDQogIGxhYnMoeD0nUmFjZS9FdGhuaWNpdHknLCB5PSAnQWdlJykrDQogIGdndGl0bGUoIkFnZSBhbmQgJ2FybWVkJyBzdGF0dXMgb2YgZGVjZWFzZWQgYnkgcmVnaW9uIikNCg0KIyBBZ2UgYnJlYWsgZG93biB3aXRoIGNsYXNzaWZpY2F0aW9uL2NhdXNlIG9mIGRlYXRoIGJ5IHJlZ2lvbg0KZ2dwbG90KGRhdGE9ZmF0YWxfcG9saWNlX3Nob290aW5nc19kYXRhLGFlcyh4PWZhdGFsX3BvbGljZV9zaG9vdGluZ3NfZGF0YSRyZWdpb24seT1hZ2UsICBmaWxsPW1hbm5lcl9vZl9kZWF0aCApKSsNCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuY29sb3VyPSJCbGFjayIsICBvdXRsaWVyLnNpemU9MSwgbm90Y2g9RkFMU0UpKw0KICBsYWJzKHg9J1JhY2UvRXRobmljaXR5JywgeT0gJ0FnZScpKw0KICBnZ3RpdGxlKCJBZ2UgYW5kIGNhdXNlIG9mIGRlYXRoIikNCg0KIyBBZ2UgYnJlYWtkb3duIHdpdGggcmFjZSBieSByZWdpb24NCmdncGxvdChkYXRhPWZhdGFsX3BvbGljZV9zaG9vdGluZ3NfZGF0YSxhZXMoeD1mYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGEkcmVnaW9uLHk9YWdlLCAgZmlsbD1yYWNlKSkrDQogIGdlb21fYm94cGxvdChvdXRsaWVyLmNvbG91cj0iQmxhY2siLCAgb3V0bGllci5zaXplPTEsIG5vdGNoPUZBTFNFKSsNCiAgbGFicyh4PSdSZWdpb24nLCB5PSAnQWdlJykNCg0KYGBgDQpgYGB7cn0NCmtub3ducmFjZWQ9c3Vic2V0KGZhdGFsX3BvbGljZV9zaG9vdGluZ3NfZGF0YSwgcmFjZSE9Ik90aGVyIiZyYWNlIT0iVW5rbm93biIpDQoNCmtub3ducmFjZWQgJT4lIGdyb3VwX2J5KHJhY2UpICU+JSBkcGx5cjo6c3VtbWFyaXNlKG4gPSBuKCkpDQoNCmBgYA0KYGBge3J9DQpnZ3Bsb3Qoa25vd25yYWNlZCxhZXMocmFjZSkpICsgDQogIGdlb21fYmFyKGZpbGw9InJveWFsYmx1ZSIpICsNCiAgZ2d0aXRsZSgiS2lsbGluZ3MgdnMgcmFjZS9ldGhuaWNpdHkgb2YgZGVjZWFzZWQiKQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShkZXZ0b29scykNCiNpbnN0YWxsLnBhY2thZ2VzKCJyZ2VvcyIpDQojaW5zdGFsbF9naXRodWIoIm10ZW5uZWtlcy90bWFwdG9vbHMiKQ0KI2luc3RhbGxfZ2l0aHViKCJtdGVubmVrZXMvdG1hcCIpDQojaW5zdGFsbC5wYWNrYWdlcygicGxvdGx5IikNCmxpYnJhcnkocmdlb3MpDQpsaWJyYXJ5KHJlbW90ZXMpDQpsaWJyYXJ5KHNoaW55KQ0KbGlicmFyeShzaGlueXRoZW1lcykNCmxpYnJhcnkoZGF0YS50YWJsZSkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KERUKQ0KbGlicmFyeShyZ2RhbCkNCmxpYnJhcnkocGxvdGx5KQ0KbGlicmFyeSh0bWFwKQ0KbGlicmFyeSh0bWFwdG9vbHMpDQpsaWJyYXJ5KHJhc3RlcikNCmxpYnJhcnkoZ3JpZCkNCmxpYnJhcnkobWFwdG9vbHMpDQpsaWJyYXJ5KHNmKQ0KbGlicmFyeShnaWZza2kpDQpsaWJyYXJ5KHJlYWR4bCkNCg0KbGlicmFyeShzaGFwZWZpbGVzKQ0KYGBgDQoNCmBgYHtyfQ0Kc2hhcGUgPC0gcmVhZF9zZigifi9Bc3NpZ25tZW50IDEvVVNBX1N0YXRlc19HZW5lcmFsaXplZC5zaHAiKQ0KDQpgYGANCmBgYHtyfQ0KIyBzcGxpdCBVUyBpbiB0aHJlZTogY29udGlndW91cywgQWxhc2thIGFuZCBIYXdhaWkNCnVzX2NvbnQgPC0gc2hhcGVbIXNoYXBlJFNUQVRFX05BTUUgJWluJSBjKCJBbGFza2EiLCAiSGF3YWlpIiwgIlB1ZXJ0byBSaWNvIiksIF0NCnVzX0FMIDwtIHNoYXBlW3NoYXBlJFNUQVRFX05BTUU9PSJBbGFza2EiLCBdDQp1c19ISSA8LSBzaGFwZVtzaGFwZSRTVEFURV9OQU1FPT0iSGF3YWlpIiwgXQ0KIA0KI1NldCBib3VuZGFyaWVzDQpVU19ib3VuZCA8LSB0bV9zaGFwZSh1c19jb250LCBwcm9qZWN0aW9uPTIxNjMpDQpBTF9ib3VuZCA8LSB0bV9zaGFwZSh1c19BTCwgcHJvamVjdGlvbiA9IDMzMzgpDQpISV9ib3VuZCA8LSB0bV9zaGFwZSh1c19ISSwgcHJvamVjdGlvbiA9IDM3NTkpDQogDQogDQojIHBsb3QgY29udGlndW91cyBzdGF0ZXMNCm1hcF9VUyA8LSBVU19ib3VuZCArDQogIHRtX3BvbHlnb25zKGNvbD0id2hpdGUiKSArIHRtX3RleHQoIlNUQVRFX05BTUUiKSsNCiAgdG1fbGF5b3V0KGZyYW1lPUZBTFNFLA0KICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gYygicmlnaHQiLCAiYm90dG9tIiksIGJnLmNvbG9yPSJsaWdodGJsdWUiLA0KICAgICAgICAgICAgaW5uZXIubWFyZ2lucyA9IGMoLjI1LC4wMiwuMDIsLjAyKSkNCiANCiMgY3JlYXRlIGluc2V0IG1hcCBvZiBBbGFza2ENCm1hcF9BTCA8LSB0bV9zaGFwZSh1c19BTCwgcHJvamVjdGlvbiA9IDMzMzgpICsgdG1fdGV4dCgiU1RBVEVfTkFNRSIpKw0KICB0bV9wb2x5Z29ucyhjb2w9IndoaXRlIixsZWdlbmQuc2hvdz1GQUxTRSkgKw0KICB0bV9sYXlvdXQodGl0bGUgPSAiQWxhc2thIixmcmFtZT1GQUxTRSwgYmcuY29sb3I9ImxpZ2h0Z3JlZW4iKQ0KIA0KIyBjcmVhdGUgaW5zZXQgbWFwIG9mIEhhd2FpaQ0KbWFwX0hJIDwtIHRtX3NoYXBlKHVzX0hJLCBwcm9qZWN0aW9uID0gMzc1OSkrIHRtX3RleHQoIlNUQVRFX05BTUUiKSsNCiAgdG1fcG9seWdvbnMoY29sPSJ3aGl0ZSIsbGVnZW5kLnNob3c9RkFMU0UpICsNCiAgdG1fbGF5b3V0KHRpdGxlID0gIkhhd2FpaSIsIGZyYW1lID0gRkFMU0UsIA0KICAgICAgICAgICAgdGl0bGUucG9zaXRpb24gPSBjKCJMRUZUIiwgIkJPVFRPTSIpLCBiZy5jb2xvcj0ibGlnaHRncmVlbiIpDQogDQpzaG9vdGluZ3Nfc2YgPC0gc3RfYXNfc2YoZmF0YWxfcG9saWNlX3Nob290aW5nc19kYXRhLCBjb29yZHMgPSBjKCdsb25naXR1ZGUnLCAnbGF0aXR1ZGUnKSwgY3JzPTQzMjYpDQoNCnttYXBfVVMgKyBtYXBfQUwrIG1hcF9ISSArICB0bV9zaGFwZShzaG9vdGluZ3Nfc2YpK3RtX2RvdHMoc2l6ZT0gMC4xLCBjb2w9InJhY2UiLCB0aXRsZT0gIlJhY2UiLCBpZD0ibmFtZSIsIHBvcHVwLnZhcnMgPSBjKCJBZ2U6IiA9ICJhZ2UiLCAiR2VuZGVyOiIgPSAiZ2VuZGVyIiwiRGF0ZSBLaWxsZWQ6Ij0iZGF0ZSIsICJBcm1lZDoiPSJhcm1lZCIsIkZsZWVpbmc6Ij0iZmxlZSIsICJTaWducyBvZiBNZW50YWwgSGVhbHRoIElzc3VlczoiID0gInNpZ25zX29mX21lbnRhbF9pbGxuZXNzIiwiTWFubmVyIG9mIERlYXRoOiAiID0gIm1hbm5lcl9vZl9kZWF0aCIsIlN0YXRlOiIgPSAic3RhdGUiKSkrDQogICAgICB0bV9sYXlvdXQodGl0bGU9ICJNYXAgb2YgRGVhZGx5IEZvcmNlIFVTIFBvbGljZSBTaG9vdGluZ3MgSmFuIDIwMTUtIERlY2VtYmVyIDIwMjEiLHRpdGxlLnBvc2l0aW9uID0gYygncmlnaHQnLCAndG9wJykpK3RtYXBfbW9kZSgidmlldyIpfQ0KDQp7IG1hcF9VUyArIG1hcF9BTCsgbWFwX0hJICsgIHRtX3NoYXBlKHNob290aW5nc19zZikrdG1fZG90cyhzaXplPSAwLjEsIGNvbD0icmFjZSIsIHRpdGxlPSAiUmFjZSIsIGlkPSJuYW1lIixwb3B1cC52YXJzID0gYygiQWdlOiIgPSAiYWdlIiwgIkdlbmRlcjoiID0gImdlbmRlciIsIkRhdGUgS2lsbGVkOiI9ImRhdGUiLCAiQXJtZWQ6Ij0iYXJtZWQiLCJGbGVlaW5nOiI9ImZsZWUiLCAiQm9keSBDYW1lcmE6Ij0iYm9keV9jYW1lcmEiLCAiU2lnbnMgb2YgTWVudGFsIEhlYWx0aCBJc3N1ZXM6IiA9ICJzaWduc19vZl9tZW50YWxfaWxsbmVzcyIsIlN0YXRlOiIgPSAic3RhdGVfbmFtZSIsICJDaXR5L0NvdW50eToiPSAiY2l0eSIpKSsNCiAgICAgIHRtX2xheW91dCh0aXRsZT0gIk1hcCBvZiBEZWFkbHkgRm9yY2UgVVMgUG9saWNlIFNob290aW5ncyBKYW4gMjAxNS0gSnVuZSAyMDIwIix0aXRsZS5wb3NpdGlvbiA9IGMoJ3JpZ2h0JywgJ3RvcCcpKSt0bWFwX21vZGUoInZpZXciKQ0KICB9KQ0KDQpgYGANCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpkZiA8LSBmYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGEgJT4lIGdyb3VwX2J5KHN0YXRlKSU+JSBzdW1tYXJpc2Uobj1uKCkpDQpmYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGEgPC1mYXRhbF9wb2xpY2Vfc2hvb3RpbmdzX2RhdGEgJT4lDQpsZWZ0X2pvaW4oDQpkZiwNCmJ5ID0gInN0YXRlIikNCg0KZmF0YWxfcG9saWNlX3Nob290aW5nc19kYXRhICU+JQ0Kc2VsZWN0KGxvbmdpdHVkZSwgbGF0aXR1ZGUsIGdyb3VwLCBhcnJvbmRfaWQpICU+JQ0KZ3JvdXBfYnkoZ3JvdXApICU+JQ0Kc3VtbWFyaXNlKG5fZGlzdGluY3QoYXJyb25kX2lkKSkgJT4lDQpzbGljZSgxOjUpDQoNCmZhdGFsX3BvbGljZV9zaG9vdGluZ3NfZGF0YSU+JQ0KZ2dwbG90KCkgKw0KZ2VvbV9wb2x5Z29uKA0KYWVzKGxvbmdpdHVkZSxsYXRpdHVkZSwgZ3JvdXAgPSBzdGF0ZSwNCmZpbGwgPSBuKSwNCmNvbG9yID0gImJsYWNrIg0KKSArDQpjb29yZF9tYXAoImJvbm5lIiwgcGFyYW1ldGVycyA9IDQ1KSArDQpzY2FsZV9maWxsX3ZpcmlkaXNfYygNCm9wdGlvbiA9ICJCIiwNCmd1aWRlID0gImxlZ2VuZCIsDQpuYW1lID0gIlRvdGFsIFNob290aW5ncyINCikgKw0KZ2VvbV90ZXh0KA0KZGF0YSA9IHN0YXRlc19jb29yZGluYXRlcywNCmFlcyhsb25naXR1ZGUsIGxhdGl0dWRlLCBsYWJlbCA9IHN0YXRlKSwNCmNvbG9yID0gIndoaXRlIg0KKSArDQp0aGVtZV9idygpICsNCmxhYnMoDQp0aXRsZSA9ICJTaG9vdGluZ3MgaGFwcGVuIGFjcm9zcyB0aGUgY291bnRyeSIsDQp4ID0gIiIsIHkgPSAiIg0KKQ0KDQpgYGANCg0K